home *** CD-ROM | disk | FTP | other *** search
- /*
- * file: SequencerTest Realtime.c
- *
- *
- */
-
-
- /*--------------------------
- Inclusions
- --------------------------*/
-
- #include <QuickDraw.h>
- #include <Windows.h>
- #include <Memory.h>
- #include <Packages.h>
-
- #include "BigEasy2.h"
- #include "BigEasyTextish.h"
- #include "BigEasyGrafish.h"
- #include "BigEasyDialogs.h"
-
- #include "SequencerTest.h"
- #include "SequencerTest Realtime.h"
-
- #include "Event Priority Queue.h"
-
- /*--------------------------
- Local Prototypes
- --------------------------*/
-
- static void DelayXUnits(long x, long units);
-
- static short GetPipDuration(ScorePart *sp,short x,short y);
-
- static void PrerollDoc(TDoc *d);
-
- /*--------------------------
- The Bronx Zoo
- --------------------------*/
-
-
- void PlayScorePartBeat(ScorePart *sp, NoteChannel nc, short beat)
- {
- unsigned long thisMask,lastMask;
- short thisElementH,lastElementH;
- short elementV;
- Boolean thisPip,lastPip;
- ComponentResult thisError;
-
- thisMask = 1L << (beat & 31);
- thisElementH = beat / 32;
-
- lastMask = 1L << (( (beat + kScoreLength - 1) % kScoreLength) & 31);
- lastElementH = ( (beat + kScoreLength - 1) % kScoreLength) / 32;
-
- for(elementV = 0; elementV < kScoreHeight; elementV++)
- {
- if(beat == kScoreLength)
- thisPip = 0;
- else
- thisPip = 0 != (sp->score[elementV][thisElementH] & thisMask);
-
- if(beat == 0)
- lastPip = 0;
- else
- lastPip = 0 != (sp->score[elementV][lastElementH] & lastMask);
-
- if(thisPip && !lastPip)
- {
- thisError = NAPlayNote(g.na,nc,kNoteRangeHigh - elementV, 64);
- ShowError(thisError);
- }
- else if(lastPip && !thisPip)
- {
- thisError = NAPlayNote(g.na,nc,kNoteRangeHigh - elementV, 0);
- ShowError(thisError);
- }
- }
- }
-
-
- void PrerollDoc(TDoc *d)
- {
- short j;
- ComponentResult thisError;
-
- #ifdef separateNoteChannel
- for(j = 0; j<kScoreParts; j++)
- {
- thisError = NAPrerollNoteChannel(g.na,d->noteChannel[j]);
- ShowError(thisError);
- }
-
- #endif
- thisError = TunePreroll(d->tp);
- ShowError(thisError);
- }
-
- void PlayDocOnce(TDoc *d)
- {
- short beat,j;
- long dummy;
- Boolean oldEngage,newEngage;
- ComponentResult thisError;
-
- PrerollDoc(d);
- oldEngage = true;
-
- for(beat = 0; beat < kScoreLength; beat ++)
- {
- newEngage = !Button();
- if(newEngage != oldEngage)
- {
- if(newEngage)
- for(j = 0; j < kScoreParts; j++)
- {
- thisError = NAEngageNoteChannel(g.na,d->noteChannel[j]);
- ShowError(thisError);
- }
- else
- for(j = 0; j < kScoreParts; j++)
- {
- thisError = NADisengageNoteChannel(g.na,d->noteChannel[j],true);
- ShowError(thisError);
- }
- oldEngage = newEngage;
- }
-
-
- for(j = 0; j<kScoreParts; j++)
- PlayScorePartBeat(&d->sr.score[j],d->noteChannel[j],beat);
- Delay(6,&dummy);
- }
-
- for(j = 0; j<kScoreParts; j++)
- PlayScorePartBeat(&d->sr.score[j],d->noteChannel[j],kScoreLength);
-
- for(j = 0; j < kScoreParts; j++)
- {
- thisError = NAEngageNoteChannel(g.na,d->noteChannel[j]);
- ShowError(thisError);
- }
-
- }
-
- short GetPipDuration(ScorePart *sp,short x,short y)
- {
- short d;
-
- d = x;
- while(x < kScoreLength && GetPipBit(sp,x,y))
- x++;
- d = x - d;
-
- return d;
- }
-
-
- void ScoreToQTScore(TDoc *d)
- {
- long i,x,y;
- ScorePart *sp;
- short lastGoodX;
- long duration;
- long time;
- long deltaTime;
- long *w;
- long timeScalar;
-
- timeScalar = 1;
-
- if(d->qtScore)
- DisposeHandle(d->qtScore);
- d->qtScore = NewHandle(40000);
- HLock(d->qtScore);
- w = (void *)*d->qtScore;
-
- lastGoodX = 0;
- for(x = 0; x < kScoreLength; x++)
- {
- for (i = 0; i < kScoreParts; i++)
- {
- sp = &d->sr.score[i];
- for (y = 0; y < kScoreHeight; y++)
- {
- if(GetPipBit(sp,x,y)
- && (x == 0 || !GetPipBit(sp,x-1,y)))
- {
- if(x > lastGoodX) /* emit rest if necessary */
- {
- duration = timeScalar * (x - lastGoodX);
- *w++ = duration;
- lastGoodX = x;
- }
-
- /*
- * emit note event
- */
- duration = timeScalar * GetPipDuration(sp,x,y);
- *w++ = 0x20000000 | (i << 24)
- | ((kNoteRangeHigh - y - 32) << 18)
- | (90L << 11)
- | duration;
- }
- }
- }
- }
-
- duration = timeScalar * (kScoreLength - lastGoodX);
- if(duration)
- *w++ = duration;
-
- *w++ = 0x60000000;
- *w++ = -1;
-
- SetHandleSize(d->qtScore,((char *)w) - ((char *)*d->qtScore));
-
- d->validQTScore = true;
- }
-
-
- void DelayXUnits(long x, long units)
- {
- long dummy;
-
- if(x < 0)
- Debugger();
-
- Delay(x * 60 / units, & dummy);
- }
-
-
- typedef enum
- {
- qNoteOff,
- qSleep
- } qCommand;
-
-
-
-
- void PlayQTScore(TDoc *d)
- {
- Handle qtScore;
- long *qtScorePtr;
- long *w;
- unsigned short command;
- unsigned long op1,op2,op3,op4;
- EPQ *q;
- EPQEvent e;
- long timeNow;
- long nextDelay;
- ComponentResult thisError;
-
- unsigned short instrument,pitch,velocity;
- long duration;
- short controller,value;
-
- PrerollDoc(d);
-
- if(!d->validQTScore)
- ScoreToQTScore(d);
-
- qtScore = d->qtScore;
-
- HLock(qtScore);
- qtScorePtr = (void *)*qtScore;
-
- q = NewEPQ(2000);
- w = qtScorePtr;
- timeNow = 0;
-
-
- while(1)
- {
- op1 = *w++;
- if(op1 == 0xFFFFffff)
- goto done;
-
- command = op1>>29;
- if(command == 0) /* rest */
- {
- e.time = timeNow + op1;
- e.data1 = qSleep;
- AddEventEPQ(q,&e);
-
- do
- {
- ExtractEventEPQ(q,&e);
- if(e.time != timeNow)
- DelayXUnits(e.time - timeNow,600);
- timeNow = e.time;
- if(e.data1 == qNoteOff)
- {
- thisError = NAPlayNote(g.na,d->noteChannel[e.data2],e.data3,0);
- ShowError(thisError);
- }
- } while(GetSizeEPQ(q) && e.data1 != qSleep);
-
- while(GetSizeEPQ(q) != 0 && PeekTopEPQ(q) == timeNow)
- {
- ExtractEventEPQ(q,&e);
- if(e.data1 == qNoteOff)
- {
- thisError = NAPlayNote(g.na,d->noteChannel[e.data2],e.data3,0);
- ShowError(thisError);
- }
- };
- }
-
- else if (command == 1)
- {
- instrument = (op1 >> 24) & 31;
- pitch = ((op1 >> 18) & 63) + 32;
- velocity = (op1>>11) & 127;
- duration = op1 & 0x03FF;
-
- thisError = NAPlayNote(g.na,d->noteChannel[instrument],pitch,velocity);
- ShowError(thisError);
-
-
- e.time = timeNow + duration;
- e.data1 = qNoteOff;
- e.data2 = instrument;
- e.data3 = pitch;
- AddEventEPQ(q,&e);
- }
- }
- done:
- DisposeEPQ(q);
-
- }
-
-